﻿using MongoDB.Bson;
using MongoDB.Bson.IO;
using MongoDB.Bson.Serialization;
using Newtonsoft.Json.Linq;
using System.Collections.Generic;

namespace StarMongoDbHelper
{
    public abstract class DBBase
    {
        public BsonDocument ToBsonDocument(JObject jo)
        {
            if (jo == null)
            {
                return null;
            }
            else
            {
                var rvdoc = BsonSerializer.Deserialize<BsonDocument>(jo.ToString(Newtonsoft.Json.Formatting.None, null));
                if (rvdoc.Contains("_id"))
                {
                    if (rvdoc["_id"].BsonType != BsonType.ObjectId && rvdoc["_id"].BsonType != BsonType.String && rvdoc["_id"].BsonType == BsonType.Document)
                    {
                        if ((rvdoc["_id"].AsBsonDocument).Contains("$oid"))
                        {
                            rvdoc["_id"] = new ObjectId(rvdoc["_id"]["$oid"].ToString());
                        }
                    }
                    else if (rvdoc["_id"].BsonType == BsonType.String)
                    {
                        rvdoc["_id"] = new ObjectId(rvdoc["_id"].ToString());
                    }
                }

                return rvdoc;

            }
        }

        public JObject parseToJObject(BsonDocument doc)
        {

            BSONHelper BH = new BSONHelper();
            return BH.parseToJObject(doc);

        }

        public JArray parseToJArray(IList<BsonDocument> list)
        {
            BSONHelper BH = new BSONHelper();
            return BH.parseToJArray(list);

        }
        public BsonDocument FormatFilter(BsonDocument f)
        {
            BsonDocument existsdoc = new BsonDocument();
            existsdoc["$exists"] = false;

            f["sys_isdelete"] = existsdoc;
            return f;
        }
        public string FormatFilter(string fliter, BsonDocument prefilter = null)
        {
            if (string.IsNullOrWhiteSpace(fliter))
            {
                fliter = "{}";
            }
            fliter = fliter.Replace("\"$array_greater_exists\":", "\"$exists\":").Replace("\"$array_less_exists\":", "\"$exists\":")
                .Replace("\"$length_equal\":", "\"$regex\":")
                .Replace("\"$length_less\":", "\"$regex\":")
                .Replace("\"$length_greater\":", "\"$regex\":")
                .Replace("\"$length_less_or_equal\":", "\"$regex\":")
                .Replace("\"$length_greater_or_equal\":", "\"$regex\":")
                .Replace("\"$length_between\":", "\"$regex\":");
            JObject sysdeljo = new JObject();
            JObject existsjo = new JObject();

            BsonDocument sysdeldoc = null;
            //如果条件中有sys_isdelete属性，则认为是获取删除的记录
            if (!fliter.Contains("sys_isdelete"))
            {
                existsjo["$exists"] = false;
                sysdeljo["sys_isdelete"] = existsjo;
                sysdeldoc = ToBsonDocument(sysdeljo);
            }
            else
            {

            }

            MongoDB.Bson.BsonDocument fdoc = MongoDB.Bson.Serialization.BsonSerializer.Deserialize<BsonDocument>(fliter);
            var jsonWriterSettings = new JsonWriterSettings { OutputMode = JsonOutputMode.CanonicalExtendedJson };
            if (fdoc.ElementCount == 0)
            {
                BsonArray ba = new BsonArray();
                if (sysdeldoc != null)
                {
                    ba.Add(sysdeldoc);
                }

                if (prefilter != null)
                {
                    ba.Add(prefilter);
                }
                fdoc["$and"] = ba;

                fliter = fdoc.ToJson(jsonWriterSettings);
            }
            else
            {
                BsonDocument Finaldoc = new BsonDocument();

                BsonArray ba = new BsonArray();
                if (sysdeldoc != null)
                {
                    ba.Add(sysdeldoc);
                }
                ba.Add(fdoc);
                if (prefilter != null)
                {
                    ba.Add(prefilter);
                }
                Finaldoc["$and"] = ba;

                fliter = Finaldoc.ToJson(jsonWriterSettings);
            }
            return fliter;
        }
    }
}
